package extras.salvation.api.methods;

import com.rsbuddy.script.methods.Calculations;
import com.rsbuddy.script.methods.Mouse;
import com.rsbuddy.script.methods.Walking;
import com.rsbuddy.script.task.Task;
import com.rsbuddy.script.wrappers.Area;
import com.rsbuddy.script.wrappers.Path;
import com.rsbuddy.script.wrappers.Tile;
import com.rsbuddy.script.wrappers.TilePath;

/**
 * @author Salvation
 * @version 1.0
 * @since 20-08-2011
 */
public final class ExtendedWalking {

	public static final int[] MUSICIANS = {8700};
	public static final int[] ANIMATION_REST = {11786, 5713};

	/**
	 * @author Salvation
	 * @param runAbove The amount of energy needed to enable running.
	 * @param walkBelow The amount of energy needed to disable running.
	 * @param restBelow The amount of energy needed to rest.
	 */
	public static void handleRun(final int runAbove, final int walkBelow, final int restBelow) {
		if (Walking.getEnergy() > runAbove && !Walking.isRunEnabled()) {
			Walking.setRun(true);
		} else if (Walking.getEnergy() < restBelow) {
			Walking.rest();
		} else if (Walking.getEnergy() < walkBelow){
			Walking.setRun(false);
		}
	}
	
	/**
	 * @author Salvation
	 * @param t The Tile to walk to.
	 * @param x The maximum division in the x-variable of a Tile.
	 * @param y The maximum division in the y-variable of a Tile.
	 * @param runAbove The amount of energy needed to enable running.
	 * @param walkBelow The amount of energy needed to disable running.
	 * @param restBelow The amount of energy needed to rest.
	 * @param sleep The amount in milliseconds to sleep as in sleep(200 * sleep, 300 * sleep).
	 */
	public static void walkTo(Tile t, final int x, final int y, final int runAbove, final int walkBelow, final int restBelow, final int sleep) {
		if (t == null) return;

		t = t.randomize(x, y);

		handleRun(runAbove, walkBelow, restBelow);

		final Path p = Walking.findPath(t);
		if (p ==  null) return;
		final Tile tile = p.getNext();
		if (tile == null) return;

		Mouse.click(tile.toMap(), true);
		Task.sleep(200 * sleep, 300 * sleep);
	}

	/**
	 * @author Salvation
	 * @param tiles The array of Tiles to be used as path.
	 * @param x The maximum division in the x-variable of a Tile.
	 * @param y The maximum division in the y-variable of a Tile.
	 * @param runAbove The amount of energy needed to enable running.
	 * @param walkBelow The amount of energy needed to disable running.
	 * @param restBelow The amount of energy needed to rest.
	 * @param sleep The amount in milliseconds to sleep as in sleep(200 * sleep, 300 * sleep).
	 */
	public static void walkTiles(final Tile[] tiles, final int x, final int y, final int runAbove, final int walkBelow, final int restBelow, final int sleep) {
		if (tiles == null) return;
		int lowDist = 100, curDist;
		int lowIndex = -1;
		final int length = tiles.length;

		for (int i = 0; i < length; i++) {
			final Tile t = tiles[i];
			curDist = Calculations.distanceTo(t);
			if (curDist < lowDist) {
				lowDist = curDist;
				lowIndex = i;
			}
		}

		if (lowIndex == -1) return;

		final int cur = lowIndex + 1;
		final int next = cur + 1;

		if (cur == length) return;

		final Tile curTile = tiles[cur];
		Tile nextTile = null;

		if (next != length)	nextTile = tiles[next];

		if (nextTile != null && nextTile.isOnMap()) {
			walkTo(nextTile, x, y, runAbove, walkBelow, restBelow, sleep);
		} else if (curTile.isOnMap()) {
			walkTo(curTile, x, y, runAbove, walkBelow, restBelow, sleep);
		} else {
			final Path p = Walking.findPath(curTile);
			if (p == null) return;
			walkTo(p.getNext(), x, y, runAbove, walkBelow, restBelow, sleep);
		}
	}
	
	/**
	 * @author Salvation
	 * @param a The area to walk to
	 * @param x The maximum division in the x-variable of a Tile.
	 * @param y The maximum division in the y-variable of a Tile.
	 * @param runAbove The amount of energy needed to enable running.
	 * @param walkBelow The amount of energy needed to disable running.
	 * @param restBelow The amount of energy needed to rest.
	 * @param sleep The amount in milliseconds to sleep as in sleep(200 * sleep, 300 * sleep).
	 */
	public static void walkTo(final Area a, final int x, final int y, final int runAbove, final int walkBelow, final int restBelow, final int sleep) {
		if (a == null) return;
		final Tile t = a.getCentralTile();
		walkTo(t, x, y, runAbove, walkBelow, restBelow, sleep);
	}

	/**
	 * @author Salvation
	 * @param path The TilePath to walk.
	 * @param x The maximum division in the x-variable of a Tile.
	 * @param y The maximum division in the y-variable of a Tile.
	 * @param runAbove The amount of energy needed to enable running.
	 * @param walkBelow The amount of energy needed to disable running.
	 * @param restBelow The amount of energy needed to rest.
	 * @param sleep The amount in milliseconds to sleep as in sleep(200 * sleep, 300 * sleep).
	 */
	public static void walkPath(final TilePath path, final int x, final int y, final int runAbove, final int walkBelow, final int restBelow, final int sleep) {
		if (path == null) return;
		final Tile t = path.getNext();
		walkTo(t, x, y, runAbove, walkBelow, restBelow, sleep);
	}
}